package com.hq.ims.data.service;

import com.hq.ims.data.config.verification.VdAdd;
import com.hq.ims.data.config.verification.VdEdit;
import com.hq.ims.data.dao.PermissionAuthorityMapper;
import com.hq.ims.data.entity.Company;
import com.hq.ims.data.entity.PermissionAuthority;
import com.hq.ims.data.entity.PermissionGroup;
import com.hq.ims.data.entity.PermissionMapAuthorityUser;
import com.hq.ims.data.entityenum.EnumGroupType;
import com.hq.ims.data.utils.ErrMsgConstant;
import com.hq.ims.data.utils.LocalConstant;
import com.hq.ims.data.vo.PermissionAuthortyMapstruct;
import com.hq.mybatis.base.BaseService;
import com.hq.mybatis.base.page.RequestPage;
import com.hq.utils.exception.CommonException;
import com.hq.utils.util.BooleanUtils;
import com.hq.utils.util.ListUtils;
import com.hq.utils.util.ObjectUtils;
import com.hq.utils.util.StringUtils;
import com.hq.web.utils.SpringBootValidateUtils;
import lombok.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * jiang bai ping
 *
 * @Email 526666031@qq.com
 * @Detail 权限组服务实现类
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class BasePermissionAuthorityService extends BaseService<PermissionAuthorityMapper, PermissionAuthority> {

    @Resource
    private BasePermissionMapAuthorityRoleService basePermissionMapAuthorityRoleService;
    @Resource
    private BasePermissionMapAuthorityUserService basePermissionMapAuthorityUserService;
    @Resource
    private BasePermissionMapAuthorityMenuService basePermissionMapAuthorityMenuService;
    @Resource
    private BaseCompanyService baseCompanyService;

    @Resource
    private BasePermissionGroupService basePermissionGroupService;

    /**
     * 分页
     */
    public List<PermissionAuthortyMapstruct.PermissionAuthorityVo> getPage(
            RequestPage page,
            PermissionAuthortyMapstruct.PageSearchVo searchVo
    ) {
        //获取列表
        this.lambdaQuery()
                .like(StringUtils.isNotEmpty(searchVo.getAuthName()), PermissionAuthority::getAuthName, searchVo.getAuthName())
                .eq(StringUtils.isNotEmpty(searchVo.getPermissionGroupId()), PermissionAuthority::getPermissionGroupId, searchVo.getPermissionGroupId())
                .eq(StringUtils.isNotEmpty(searchVo.getCompanyId()), PermissionAuthority::getCompanyId, searchVo.getCompanyId())
                .page(page);

        List<PermissionAuthority> records = page.getRecords();
        List<PermissionAuthortyMapstruct.PermissionAuthorityVo> voList = PermissionAuthortyMapstruct.INSTANCE.toPermissionAuthorityVoList(records);

        return voList;
    }

    /**
     * 检查是否存在权限组
     */
    public PermissionAuthority notExistsTh(String authId) {
        PermissionAuthority permissionGroup = this.getById(authId);
        if (permissionGroup == null) {
            throw CommonException.build("不存在该权限组数据,无法进行其他操作,请联系管理员。请求的groupId：" + authId);
        }
        return permissionGroup;
    }

    /**
     * 添加权限组数据
     */
    @Transactional(rollbackFor = Exception.class)
    public void addData(
            PermissionAuthortyMapstruct.SaveVo saveVo
    ) {
        SpringBootValidateUtils.validate(saveVo, VdAdd.class);
        //验证公司
        Company company = baseCompanyService.getById(saveVo.getCompanyId());
        ObjectUtils.isNullThrow(company, ErrMsgConstant.COMPANY_INFO_NOT_EXISTS);

        //名称是否重复
        BooleanUtils.isTrueThrow(
                this.isExistsName(saveVo.getAuthName(), saveVo.getCompanyId(), null),
                ErrMsgConstant.PERMISSION_AUTH_NAME_EXISTS
        );

        PermissionGroup permissionGroup = basePermissionGroupService.getById(saveVo.getPermissionGroupId());
        ObjectUtils.isNullThrow(permissionGroup, ErrMsgConstant.PERMISSION_GROUP_NOT_EXISTS);
        BooleanUtils.isTrueThrow(permissionGroup.getGroupType() != EnumGroupType.Auth, ErrMsgConstant.PERMISSION_AUTH_GROUP_NOT_EXISTS);

        PermissionAuthority permissionAuthority = new PermissionAuthority();
        permissionAuthority.setSortNumber(1);
        permissionAuthority.setAuthName(saveVo.getAuthName());
        permissionAuthority.setCompanyId(saveVo.getCompanyId());
        permissionAuthority.setPermissionGroupId(saveVo.getPermissionGroupId());
        permissionAuthority.setIsAllowEdit(true);
        boolean bl = permissionAuthority.insert();

    }

    /**
     * 更新权限组
     */
    @Transactional(rollbackFor = Exception.class)
    public void updateAuth(
            PermissionAuthortyMapstruct.SaveVo saveVo
    ) {
        SpringBootValidateUtils.validate(saveVo, VdEdit.class);
        //验证公司
        Company company = baseCompanyService.getById(saveVo.getCompanyId());
        ObjectUtils.isNullThrow(company, ErrMsgConstant.COMPANY_INFO_NOT_EXISTS);

        //名称是否重复
        BooleanUtils.isTrueThrow(
                this.isExistsName(saveVo.getAuthName(), saveVo.getCompanyId(), saveVo.getPermissionAuthorityId()),
                ErrMsgConstant.PERMISSION_AUTH_NAME_EXISTS
        );

        PermissionAuthority permissionAuthority = this.getById(saveVo.getPermissionAuthorityId());
        ObjectUtils.isNullThrow(permissionAuthority, ErrMsgConstant.PERMISSION_AUTH_NOT_EXISTS);

        permissionAuthority.setAuthName(saveVo.getAuthName());
        permissionAuthority.setCompanyId(saveVo.getCompanyId());
        permissionAuthority.setPermissionGroupId(saveVo.getPermissionGroupId());
        permissionAuthority.setIsAllowEdit(true);
        boolean bl = permissionAuthority.updateById();
    }

    /**
     * 检查组是否重名
     */
    private boolean isExistsName(
            String authName,
            String companyId,
            String excludeId
    ) {
        return this.lambdaQuery()
                .eq(PermissionAuthority::getAuthName, authName)
                .eq(StringUtils.isNotEmpty(companyId), PermissionAuthority::getCompanyId, companyId)
                .eq(StringUtils.isNotEmpty(excludeId), PermissionAuthority::getPermissionAuthorityId, excludeId)
                .count() > 0;
    }

    /**
     * 公司是否存在该权限
     */
    public boolean isExistsCompanyAuth(
            String authId,
            String companyId
    ) {
        return this.lambdaQuery()
                .eq(PermissionAuthority::getCompanyId, companyId)
                .eq(PermissionAuthority::getPermissionAuthorityId, authId)
                .count() > 0;
    }


    /**
     * 删除权限组
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean delByAuthId(String authId) {
        StringUtils.verificationEmpty(authId, ErrMsgConstant.PERMISSION_AUTH_NOT_EXISTS);

        //1.删除权限和角色绑定-角色数据
        basePermissionMapAuthorityRoleService.delByAuthId(authId);
        //2.删除权限组-用户数据
        basePermissionMapAuthorityUserService.delByAuthId(authId);
        //4.删除权限组
        this.lambdaUpdate()
                .eq(PermissionAuthority::getPermissionAuthorityId, authId)
                .remove();
        return true;
    }

    /**
     * 通过用户id+公司id获取用户加入的权
     */
    public List<PermissionAuthority> getAuthByUserIdAndCompanyId(String userId, String companyId) {
        if (StringUtils.isEmpty(userId) || StringUtils.isEmpty(companyId)) {
            throw CommonException.build(ErrMsgConstant.PARAM_INPUT_ERROR);
        }
        List<PermissionMapAuthorityUser> permissionMapAuthorityUserList = basePermissionMapAuthorityUserService.lambdaQuery()
                .eq(PermissionMapAuthorityUser::getUserId, userId)
                .eq(StringUtils.isNotEmpty(companyId), PermissionMapAuthorityUser::getCompanyId, companyId)
                .list();
        List<String> groupIds = permissionMapAuthorityUserList.stream().map(PermissionMapAuthorityUser::getPermissionAuthorityId).distinct().collect(Collectors.toList());
        if (ListUtils.isNotExistsEle(groupIds)) {
            return new ArrayList<>();
        }
        return this.lambdaQuery()
                .in(PermissionAuthority::getPermissionAuthorityId, groupIds)
                .list();
    }

    /**
     * 通过公司id获权限
     */
    public List<PermissionAuthority> getAuthCompanyId(@NonNull String companyId) {
        List<PermissionAuthority> permissionMapAuthorityUserList = this.lambdaQuery()
                .eq(StringUtils.isNotEmpty(companyId), PermissionAuthority::getCompanyId, companyId)
                .list();
        return permissionMapAuthorityUserList;
    }

    /**
     * 根据权限ID和公司ID获取权限
     */
    public PermissionAuthority getAuthByAuthIdAndCompanyId(
            @NonNull String authId,
            @NonNull String companyId
    ) {
        PermissionAuthority permissionAuthority = this.lambdaQuery()
                .eq(PermissionAuthority::getPermissionAuthorityId, authId)
                .eq(PermissionAuthority::getCompanyId, companyId)
                .last(LocalConstant.LIMIT_1)
                .one();
        return permissionAuthority;
    }


    /**
     * 这个组下面有多少条权限数据
     */
    public long groupDataCount(String permissionGroupId) {
        Long count = this.lambdaQuery().eq(PermissionAuthority::getPermissionGroupId, permissionGroupId).count();
        return count.longValue();
    }

    /**
     * 这个组是否存在数据
     */
    public boolean groupDataIsExists(String permissionGroupId) {
        return groupDataCount(permissionGroupId) > 0;
    }

    /**
     * 获取权限绑定角色详情
     *
     * @param permissionAuthorityId 权限ID
     */
    public PermissionAuthortyMapstruct.PermissionAuthorityVo getBindAuthRoleDetail(String permissionAuthorityId) {
        PermissionAuthority permissionAuthority = this.getById(permissionAuthorityId);
        PermissionAuthortyMapstruct.PermissionAuthorityVo vo = PermissionAuthortyMapstruct.INSTANCE.toPermissionAuthorityVo(permissionAuthority);
        if (vo == null) {
            return vo;
        }
        //获取权限
        List<String> authIdListByRoleIdList = basePermissionMapAuthorityRoleService.getRoleIdListByAuthIdList(Arrays.asList(permissionAuthority.getPermissionAuthorityId()));
        vo.setRoleIdList(authIdListByRoleIdList);
        return vo;
    }

    /**
     * 获取权限绑定菜单详情
     *
     * @param permissionAuthorityId 权限ID
     */
    public PermissionAuthortyMapstruct.PermissionAuthorityVo getBindAuthMenuDetail(String permissionAuthorityId) {
        PermissionAuthority permissionAuthority = this.getById(permissionAuthorityId);
        PermissionAuthortyMapstruct.PermissionAuthorityVo vo = PermissionAuthortyMapstruct.INSTANCE.toPermissionAuthorityVo(permissionAuthority);
        if (vo == null) {
            return vo;
        }
        //获取权限
        List<String> authIdListByRoleIdList = basePermissionMapAuthorityMenuService.getMenuIdListByAuthIdList(Arrays.asList(permissionAuthority.getPermissionAuthorityId()));
        vo.setRoleIdList(authIdListByRoleIdList);
        return vo;
    }

    @Transactional(rollbackFor = Exception.class)
    public void delByCompanyId(String companyId) {
        this.lambdaUpdate().eq(PermissionAuthority::getCompanyId,companyId).remove();
    }
}
